package sesion;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.lang.reflect.ParameterizedType;
import javax.persistence.Query;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;


public class GenericJpaDao<T, ID extends Serializable> implements GenericDao<T, ID>{

	protected final Class<T> persistentClass;
	protected final EntityManagerFactory emf = EMFService.get();
    
    @SuppressWarnings("unchecked")
	public GenericJpaDao() {
    persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }
    
	@SuppressWarnings("unchecked")
	@Override
	public List<T> findAll() {
		EntityManager em = null;
	    try {
	        em = emf.createEntityManager();
	        Query query = em.createQuery("select m from " + persistentClass.getSimpleName()+" m");
	        return query.getResultList();
	    } catch (Exception ex) {
	        ex.printStackTrace();
	    }
	    finally
	    {
	    	em.close();
	    }
	    return new ArrayList<T>();
	}
	
	
	@Override
	public void save(T entity) {
		EntityManager em = null;
	    EntityTransaction tx = null;

	    try {
	        em = emf.createEntityManager();
	        tx = em.getTransaction();
	        tx.begin();
	        em.persist(entity);
	        tx.commit();
	    } catch (Exception ex) {
	    	ex.printStackTrace();
	        if (tx != null) {
	        tx.rollback();
	        }
	    }
	    finally
	    {
	    	em.close();
	    }
	}
	


	@Override
	public T findById(ID id) {
		T result = null;

	    EntityManager em = null;
	    EntityTransaction tx = null;

	    try {
	        em = emf.createEntityManager();
	        tx = em.getTransaction();
	        tx.begin();
	        result = em.find(persistentClass, id);
	        tx.commit();
	    } catch (Exception ex) {
	    	ex.printStackTrace();
	        if (tx != null) {
	        tx.rollback();
	        }
	    }
	    finally
	    {
	    	em.close();
	    }

	    return result;
	}

	@Override
	public void update(T entity) {
		EntityManager em = null;
	    EntityTransaction tx = null;

	    try {
	        em = emf.createEntityManager();
	        tx = em.getTransaction();
	        tx.begin();
	        em.merge(entity);
	        tx.commit();
	    } catch (Exception ex) {
	    	ex.printStackTrace();
	        if (tx != null) {
	        tx.rollback();
	        }
	    }
	    finally
	    {
	    	em.close();
	    }
	}

	@Override
	public void delete(T entity) {
		EntityManager em = null;
	    EntityTransaction tx = null;

	    try {
	        em = emf.createEntityManager();
	        tx = em.getTransaction();
	        tx.begin();
	        em.remove(entity);
	        tx.commit();
	    } catch (Exception ex) {
	    	ex.printStackTrace();
	        if (tx != null) {
	        tx.rollback();
	        }
	    }
	    finally
	    {
	    	em.close();
	    }
	}

	@Override
	public void izbrisiKorisnika(String pom) {
		EntityManager em = null;
	    EntityTransaction tx = null;

	    try {
	        em = emf.createEntityManager();
	        tx = em.getTransaction();
	        tx.begin();
	        Query query = em.createQuery("select m from " + persistentClass.getSimpleName()+" m where m.koisnickoIme='"+pom+"'");
			@SuppressWarnings("unchecked")
			T korisnik = (T) query.getSingleResult();
	        if(korisnik!=null)
	        {
	        	em.remove(korisnik);
	        	tx.commit();
	        }
	    } catch (Exception ex) {
	    	ex.printStackTrace();
	        if (tx != null) {
	        tx.rollback();
	        }
	    }
	    finally
	    {
	    	em.close();
	    }
	}
}
